#include "cpu/exec/template-start.h"

#define instr jmp

make_helper(concat(jmp_i_,SUFFIX)) {
        int len = concat(decode_i_,SUFFIX)(eip + 1);
        cpu.eip +=(DATA_TYPE_S)op_src->val;
        print_asm("jmp: 0x%x", cpu.eip+len+1);
        return len + 1;
}

make_helper(concat(jmp_rm_,SUFFIX)) {
	int len = concat(decode_rm_,SUFFIX)(eip + 1);
	cpu.eip = (DATA_TYPE_S)op_src->val - len - 1;
	print_asm("jmp: %s", op_src->str);
	return len + 1;
}

#if DATA_BYTE==4

extern Sreg_Descriptor* sreg_descriptor;
Sreg_Descriptor new_sreg_descri;

make_helper(ljmp){
	sreg_descriptor=&new_sreg_descri;
	uint32_t count1=instr_fetch(cpu.eip+1,4);
	uint16_t count2=instr_fetch(cpu.eip+1+4,2);
	cpu.eip=count1-7;
	cpu.cs.selector=count2;
	uint16_t index=cpu.cs.selector>>3;

	Assert((index<<3)<=cpu.gdtr.limit,"The segement selector is out of limit!");

	uint32_t chart_addr=cpu.gdtr.base+(index<<3);
	sreg_descriptor->part1=lnaddr_read(chart_addr,4);
	sreg_descriptor->part2=lnaddr_read(chart_addr+4,4);

	Assert(sreg_descriptor->P==1,"The segement don't exsit!");

	uint32_t basec=0;
        basec|=((uint32_t)sreg_descriptor->base1);
	basec|=(((uint32_t)sreg_descriptor->base2)<<16);
        basec|=(((uint32_t)sreg_descriptor->base3)<<24);
	cpu.cs.base=basec;

	uint32_t limitc=0;
	limitc|=((uint32_t)sreg_descriptor->limit1);
	limitc|=(((uint32_t)sreg_descriptor->limit2)<<16);
	limitc|=(((uint32_t)0xfff)<<24);
	cpu.cs.limit=limitc;

	if(sreg_descriptor->G==1)
		cpu.cs.limit<<=12;
	
	print_asm("ljump %x %x",count2,count1);
	return 7;
}

#endif

#include "cpu/exec/template-end.h"

